// ======================================================================== // Copyright (C) zeroth Project Team. All rights reserved. // GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 // http://www.gnu.org/licenses/agpl-3.0.txt // ======================================================================== package zeroth.framework.screen.iface.jsf; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.logging.Logger; import javax.el.ValueExpression; import javax.faces.FacesException; import javax.faces.component.EditableValueHolder; import javax.faces.component.UIComponent; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import javax.faces.render.FacesRenderer; import javax.faces.render.Renderer; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.FileItem; import org.apache.commons.lang3.StringUtils; /** * アップロードのレンダラ * @author nilcy */ @FacesRenderer(componentFamily = "javax.faces.Input", rendererType = "zeroth.faces.Upload") public class UploadRenderer extends Renderer { /** inputタグ */ private static final String TAG_INPUT = "input"; /** typeタグ */ private static final String TAG_TYPE = "type"; /** fileタグ */ private static final String TAG_FILE = "file"; /** nameタグ */ private static final String TAG_NAME = "name"; /** clientIdタグ */ private static final String TAG_CLIENT_ID = "clientId"; /** 記録者 */ private static final Logger LOG = Logger.getAnonymousLogger(); /** 実体化 */ public UploadRenderer() { super(); } /** {@inheritDoc} */ @SuppressWarnings("resource") @Override public void encodeBegin(final FacesContext context, final UIComponent component) throws IOException { if (!component.isRendered()) { return; } final ResponseWriter writer = context.getResponseWriter(); final String clientId = component.getClientId(context); writer.startElement(TAG_INPUT, component); writer.writeAttribute(TAG_TYPE, TAG_FILE, TAG_TYPE); writer.writeAttribute(TAG_NAME, clientId, TAG_CLIENT_ID); writer.endElement(TAG_INPUT); writer.flush(); } /** {@inheritDoc} */ @Override public void decode(final FacesContext context, final UIComponent component) { final ExternalContext external = context.getExternalContext(); final HttpServletRequest request = (HttpServletRequest) external.getRequest(); final String clientId = component.getClientId(context); final FileItem item = (FileItem) request.getAttribute(clientId); if ((item == null) || StringUtils.isEmpty(item.getName())) { return; } LOG.fine("item:" + item); final ValueExpression valueExpr = component.getValueExpression("value"); if (valueExpr != null) { ((EditableValueHolder) component).setSubmittedValue(findSubmittedValue(request, item, valueExpr.getType(context.getELContext()))); ((EditableValueHolder) component).setValid(true); } final Object target = component.getAttributes().get("target"); LOG.fine("target=" + target); if (target != null) { File file; if (target instanceof File) { file = (File) target; } else { final ServletContext servletContext = (ServletContext) external.getContext(); final String itemName = item.getName(); final String dirPath = "WEB-INF/" + target; LOG.fine("dirPath=" + dirPath); new File(servletContext.getRealPath(dirPath)).mkdirs(); final String filePath = dirPath + "/" + itemName; final String realPath = servletContext.getRealPath(filePath); LOG.fine("realPath=" + realPath); file = new File(realPath); } // UGH 汎用例外クラスを捕捉したくないがcommons-upload仕様が… try { LOG.fine("item.write"); item.write(file); } catch (final Exception ex) { throw new FacesException(ex); } } } /** * 画面値の取得 * @param request HTTP要求 * @param item FILE項目 * @param valueType 値型 * @return 画面値 * @throws FacesException 画面例外 */ @SuppressWarnings("static-method") private Object findSubmittedValue(final HttpServletRequest request, final FileItem item, final Class<?> valueType) throws FacesException { Object newValue; if (valueType == byte[].class) { newValue = item.get(); } else if (valueType == InputStream.class) { try { newValue = item.getInputStream(); } catch (final IOException ex) { throw new FacesException(ex); } } else { final String encoding = request.getCharacterEncoding(); if (encoding != null) { try { newValue = item.getString(encoding); } catch (final UnsupportedEncodingException ex) { newValue = item.getString(); } } else { newValue = item.getString(); } } return newValue; } }